#pragma once

#include <string>
#include <vector>
#include <memory>
#include <map>

namespace viml {

// Token类型枚举
enum class TokenType {
    // 字面量
    NUMBER,         // 数字常量
    STRING,         // 字符串常量
    IDENTIFIER,     // 标识符
    
    // 关键字
    LET,            // let
    IF,             // if
    ELSEIF,         // elseif
    ELSE,           // else
    ENDIF,          // endif
    WHILE,          // while
    ENDWHILE,       // endwhile
    FOR,            // for
    IN,             // in
    ENDFOR,         // endfor
    FUNCTION,       // function
    ENDFUNCTION,    // endfunction
    RETURN,         // return
    ECHO,           // echo
    CALL,           // call
    
    // 操作符
    ASSIGN,         // =
    PLUS,           // +
    MINUS,          // -
    MULTIPLY,       // *
    DIVIDE,         // /
    MODULO,         // %
    
    // 比较操作符
    EQUAL,          // ==
    NOT_EQUAL,      // !=
    LESS_THAN,      // <
    LESS_EQUAL,     // <=
    GREATER_THAN,   // >
    GREATER_EQUAL,  // >=
    
    // 逻辑操作符
    AND,            // &&
    OR,             // ||
    NOT,            // !
    
    // 分隔符
    LPAREN,         // (
    RPAREN,         // )
    LBRACKET,       // [
    RBRACKET,       // ]
    LBRACE,         // {
    RBRACE,         // }
    COMMA,          // ,
    DOT,            // .
    COLON,          // :
    SEMICOLON,      // ;
    
    // 特殊常量
    SPECIAL_CONSTANT, // v:开头的特殊常量
    
    // 特殊
    NEWLINE,        // 换行符
    END_OF_FILE,    // 文件结束
    UNKNOWN         // 未知字符
};

// Token结构
struct Token {
    TokenType type;
    std::string value;
    size_t line;
    size_t column;
    
    Token(TokenType t, const std::string& v, size_t l, size_t c)
        : type(t), value(v), line(l), column(c) {}
};

// 词法分析器类
class Lexer {
private:
    std::string source;
    size_t position;
    size_t line;
    size_t column;
    char current_char;
    
    // 关键字映射表
    static std::map<std::string, TokenType> keywords;
    
    // 辅助方法
    void advance();
    void skip_whitespace();
    void skip_comment();
    char peek();
    std::string read_number();
    std::string read_string(char quote_type = '\0');
    std::string read_identifier();
    TokenType get_keyword_type(const std::string& word);
    
public:
    explicit Lexer(const std::string& src);
    
    // 获取下一个token
    Token next_token();
    
    // 预览下一个token但不消费
    Token peek_token();
    
    // 获取所有tokens
    std::vector<Token> tokenize();
    
    // 错误处理
    void error(const std::string& message);
    
    // 当前位置信息
    size_t get_line() const { return line; }
    size_t get_column() const { return column; }
};

// 将Token类型转换为字符串（用于调试）
std::string token_type_to_string(TokenType type);

} // namespace viml